Outdated CHICKEN release

This is a manual page for an old and unsupported version of CHICKEN. If you are still using it, please consider migrating to the latest version. You can find the manual for the latest release here.

  1. Outdated CHICKEN release
  2. C interface
    1. C_save
    2. C_restore
    3. C_fix
    4. C_make_character
    5. C_SCHEME_END_OF_LIST
    6. C_word C_SCHEME_END_OF_FILE
    7. C_word C_SCHEME_FALSE
    8. C_word C_SCHEME_TRUE
    9. C_string
    10. C_string2
    11. C_intern2
    12. C_intern3
    13. C_pair
    14. C_flonum
    15. C_int_to_num
    16. C_mpointer
    17. C_vector
    18. C_list
    19. C_alloc
    20. C_SIZEOF_LIST
    21. C_SIZEOF_STRING
    22. C_SIZEOF_VECTOR
    23. C_SIZEOF_INTERNED_SYMBOL
    24. C_SIZEOF_PAIR
    25. C_SIZEOF_FLONUM
    26. C_SIZEOF_POINTER
    27. C_SIZEOF_LOCATIVE
    28. C_SIZEOF_TAGGED_POINTER
    29. C_character_code
    30. C_unfix
    31. C_flonum_magnitude
    32. C_c_string
    33. C_num_to_int
    34. C_pointer_address
    35. C_header_size
    36. C_header_bits
    37. C_block_item
    38. C_u_i_car
    39. C_u_i_cdr
    40. C_data_pointer
    41. C_make_header
    42. C_mutate
    43. C_symbol_value
    44. C_gc_protect
    45. C_gc_unprotect
    46. C_pre_gc_hook
    47. C_post_gc_hook
    48. An example for simple calls to foreign code involving callbacks
    49. Notes:

C interface

The following functions and macros are available for C code that invokes Scheme or foreign procedures that are called by Scheme:

C_save

[C macro] void C_save (C_word x) :

Saves the Scheme data object x on the temporary stack.

C_restore

[C macro] void C_restore

Pops and returns the topmost value from the temporary stack.

C_fix

[C macro] C_word C_fix (int integer)

C_make_character

[C macro] C_word C_make_character (int char_code)

C_SCHEME_END_OF_LIST

[C macro] C_SCHEME_END_OF_LIST

C_word C_SCHEME_END_OF_FILE

[C macro] C_SCHEME_END_OF_FILE

C_word C_SCHEME_FALSE

[C macro] C_SCHEME_FALSE

C_word C_SCHEME_TRUE

[C macro] C_SCHEME_TRUE

These macros return immediate Scheme data objects.

C_string

[C function] C_word C_string (C_word **ptr, int length, char *string)

C_string2

[C function] C_word C_string2 (C_word **ptr, char *zero_terminated_string)

C_intern2

[C function] C_word C_intern2 (C_word **ptr, char *zero_terminated_string)

C_intern3

[C function] C_word C_intern3 (C_word **ptr, char *zero_terminated_string, C_word initial_value)

C_pair

[C function] C_word C_pair (C_word **ptr, C_word car, C_word cdr)

C_flonum

[C function] C_word C_flonum (C_word **ptr, double number)

C_int_to_num

[C function] C_word C_int_to_num (C_word **ptr, int integer)

C_mpointer

[C function] C_word C_mpointer (C_word **ptr, void *pointer)

C_vector

[C function] C_word C_vector (C_word **ptr, int length, ...)

C_list

[C function] C_word C_list (C_word **ptr, int length, ...)

These functions allocate memory from ptr and initialize a fresh data object. The new data object is returned. ptr should be the address of an allocation pointer created with C_alloc.

C_alloc

[C macro] C_word* C_alloc (int words)

Allocates memory from the C stack (C_alloc) and returns a pointer to it. words should be the number of words needed for all data objects that are to be created in this function. Note that stack-allocated data objects have to be passed to Scheme callback functions, or they will not be seen by the garbage collector. This is really only usable for callback procedure invocations, make sure not to use it in normal code, because the allocated memory will be re-used after the foreign procedure returns. When invoking Scheme callback procedures a minor garbage collection is performed, so data allocated with C_alloc will already have moved to a safe place.

Note that C_alloc is really just a wrapper around alloca, and can also be simulated by declaring a stack-allocated array of C_words:

C_SIZEOF_LIST

[C macro] int C_SIZEOF_LIST (int length)

C_SIZEOF_STRING

[C macro] int C_SIZEOF_STRING (int length)

C_SIZEOF_VECTOR

[C macro] int C_SIZEOF_VECTOR (int length)

C_SIZEOF_INTERNED_SYMBOL

[C macro] int C_SIZEOF_INTERNED_SYMBOL (int length)

C_SIZEOF_PAIR

[C macro] int C_SIZEOF_PAIR

C_SIZEOF_FLONUM

[C macro] int C_SIZEOF_FLONUM

C_SIZEOF_POINTER

[C macro] int C_SIZEOF_POINTER

C_SIZEOF_LOCATIVE

[C macro] int C_SIZEOF_LOCATIVE

C_SIZEOF_TAGGED_POINTER

[C macro] int C_SIZEOF_TAGGED_POINTER

These are macros that return the size in words needed for a data object of a given type.

C_character_code

[C macro] int C_character_code (C_word character)

C_unfix

[C macro] int C_unfix (C_word fixnum)

C_flonum_magnitude

[C macro] double C_flonum_magnitude (C_word flonum)

C_c_string

[C function] char* C_c_string (C_word string)

C_num_to_int

[C function] int C_num_to_int (C_word fixnum_or_flonum)

C_pointer_address

[C function] void* C_pointer_address (C_word pointer)

These macros and functions can be used to convert Scheme data objects back to C data. Note that C_c_string() returns a pointer to the character buffer of the actual Scheme object and is not zero-terminated.

C_header_size

[C macro] int C_header_size (C_word x)

C_header_bits

[C macro] int C_header_bits (C_word x)

Return the number of elements and the type-bits of the non-immediate Scheme data object x.

C_block_item

[C macro] C_word C_block_item (C_word x, int index)

This macro can be used to access slots of the non-immediate Scheme data object x. index specifies the index of the slot to be fetched, starting at 0. Pairs have 2 slots, one for the car and one for the cdr. Vectors have one slot for each element.

C_u_i_car

[C macro] C_word C_u_i_car (C_word x)

C_u_i_cdr

[C macro] C_word C_u_i_cdr (C_word x)

Aliases for C_block_item(x, 0) and C_block_item(x, 1), respectively.

C_data_pointer

[C macro] void* C_data_pointer (C_word x)

Returns a pointer to the data-section of a non-immediate Scheme object.

C_make_header

[C macro] C_word C_make_header (C_word bits, C_word size)

A macro to build a Scheme object header from its bits and size parts.

C_mutate

[C function] C_word C_mutate (C_word *slot, C_word val)

Assign the Scheme value val to the location specified by slot. If the value points to data inside the nursery (the first heap-generation), then the garbage collector will remember to handle the data appropriately. Assigning nursery-pointers directly will otherwise result in lost data. Note that no copying takes place at the moment when C_mutate is called, but later - at the next (minor) garbage collection.

C_symbol_value

[C macro] C_word C_symbol_value (C_word symbol)

Returns the global value of the variable with the name symbol. If the variable is unbound C_SCHEME_UNBOUND is returned. You can set a variable's value with C_mutate(&C_symbol_value(SYMBOL), VALUE).

C_gc_protect

[C function] void C_gc_protect (C_word *ptrs[], int n)

Registers n variables at address ptrs to be garbage collection roots. The locations should not contain pointers to data allocated in the nursery, only immediate values or pointers to heap-data are valid. Any assignment of potential nursery data into a root-array should be done via C_mutate(). The variables have to be initialized to sensible values before the next garbage collection starts (when in doubt, set all locations in ptrs to C_SCHEME_UNDEFINED) C_gc_protect may not called before the runtime system has been initialized (either by CHICKEN_initialize, CHICKEN_run or CHICKEN_invoke.

For a slightly simpler interface to creating and using GC roots see CHICKEN_new_gc_root.

C_gc_unprotect

[C function] void C_gc_unprotect (int n)

Removes the last n registered variables from the set of root variables.

C_pre_gc_hook

[C Variable] void (*C_pre_gc_hook)(int mode)

If not NULL, the function pointed to by this variable will be called before each garbage collection with a flag indicating what kind of collection was performed (either 0 for a minor collection or 2 for a resizing collection). A "resizing" collection means a secondary collection that moves all live data into a enlarged (or shrinked) heap-space. Minor collections happen very frequently, so the hook function should not consume too much time. The hook function may not invoke Scheme callbacks.

Note that resizing collections may be nested in normal major collections.

C_post_gc_hook

[C Variable] void (*C_post_gc_hook)(int mode, long ms)

If not NULL, the function pointed to by this variable will be called after each garbage collection with a flag indicating what kind of collection was performed (either 0 for a minor collection, 1 for a major collection or 2 for a resizing collection). Minor collections happen very frequently, so the hook function should not consume too much time. The hook function may not invoke Scheme callbacks. The ms argument records the number of milliseconds required for the garbage collection, if the collection was a major one. For minor collections the value of the ms argument is undefined.

An example for simple calls to foreign code involving callbacks

% cat foo.scm
#>
extern int callout(int, int, int);
<#

(define callout (foreign-safe-lambda int "callout" int int int))

(define-external (callin (scheme-object xyz)) int
  (print "This is 'callin': " xyz)
  123)

(print (callout 1 2 3))
% cat bar.c
#include <stdio.h>
#include "chicken.h"

extern int callout(int, int, int);
extern int callin(C_word x);

int callout(int x, int y, int z)
{
  C_word *ptr = C_alloc(C_SIZEOF_LIST(3));
  C_word lst;

  printf("This is 'callout': %d, %d, %d\n", x, y, z);
  lst = C_list(&ptr, 3, C_fix(x), C_fix(y), C_fix(z));
  return callin(lst);  /* Note: `callin' will have GC'd the data in `ptr' */
}
% csc foo.scm bar.c -o foo
% foo
This is 'callout': 1, 2, 3
This is 'callin': (1 2 3)
123

Notes:

Scheme procedures can call C functions, and C functions can call Scheme procedures, but for every pending C stack frame, the available size of the first heap generation (the nursery) will be decreased, because the C stack is identical to the nursery. On systems with a small nursery this might result in thrashing, since the C code between the invocation of C from Scheme and the actual calling back to Scheme might build up several stack-frames or allocates large amounts of stack data. To prevent this it is advisable to increase the default nursery size, either when compiling the file (using the -nursery option) or when running the executable (using the -:s runtime option).

Calls to Scheme/C may be nested arbitrarily, and Scheme continuations can be invoked as usual, but keep in mind that C stack frames will not be recovered, when a Scheme procedure call from C does not return normally.

When multiple threads are running concurrently, and control switches from one thread to another, then the continuation of the current thread is captured and saved. Any pending C stack frame still active from a callback will remain on the stack until the threads is re-activated again. This means that in a multithreading situation, when C callbacks are involved, the available nursery space can be smaller than expected. So doing many nested Scheme->C->Scheme calls can reduce the available memory up to the point of thrashing. It is advisable to have only a single thread with pending C stack-frames at any given time.

Pointers to Scheme data objects should not be stored in local or global variables while calling back to Scheme. Any Scheme object not passed back to Scheme will be reclaimed or moved by the garbage collector.

Calls from C to Scheme are never tail-recursive.

Continuations captured via call-with-current-continuation and passed to C code can be invoked like any other Scheme procedure.

Previous: Other support procedures

Next: chicken-setup